/**
 Ceated by Amit Mudgal (MicroStrategy Principal Designer) for GMS on 6/20/2014
 *
 */
package com.amex.uam.tasks;

import java.util.ArrayList;
import java.util.List;

import com.amex.SQL.Utils;
import com.amex.uam.pojo.MSLogin;
import com.amex.uam.pojo.SecurityGroupBean;
import com.microstrategy.web.beans.BeanFactory;
import com.microstrategy.web.beans.UserEntitiesBean;
import com.microstrategy.web.beans.UserGroupBean;
import com.microstrategy.web.beans.WebBeanException;
import com.microstrategy.web.objects.WebFolder;
import com.microstrategy.web.objects.WebIServerSession;
import com.microstrategy.web.objects.WebObjectInfo;
import com.microstrategy.web.objects.WebObjectSource;
import com.microstrategy.web.objects.WebObjectsException;
import com.microstrategy.web.objects.WebObjectsFactory;
import com.microstrategy.web.objects.WebSearch;
import com.microstrategy.webapi.EnumDSSXMLApplicationType;
import com.microstrategy.webapi.EnumDSSXMLObjectSubTypes;
import com.microstrategy.webapi.EnumDSSXMLSearchDomain;
import com.microstrategy.webapi.EnumDSSXMLSearchFlags;


public class MDServiceHandler {

	
    private static String BASE_GROUP_MARC = "MicroStrategy Groups";
    private static String BASE_GROUP_ICARD = "System Monitors";
    private static String BASE_GROUP_DASHBOARD = "Narrowcast System Administrators";
    
	public static List<List<SecurityGroupBean>> getGroups(MSLogin user){
		List<List<SecurityGroupBean>> result = new ArrayList<List<SecurityGroupBean>>();
		boolean MARC_Access = false;
		boolean ICARD_Access = false;
		boolean Dashboard_Access = false;
		if(user.getProducts().contains("MARC")){
			MARC_Access = true;
		}
		if(user.getProducts().contains("ICARD")){
			ICARD_Access = true; 
		}
		if(user.getProducts().contains("Dashboard")){
			Dashboard_Access = true;
		}
		WebIServerSession  sessioninfo = GetAdminSession(user);
		WebObjectSource wos = sessioninfo.getFactory().getObjectSource();
		WebSearch search = wos.getNewSearchObject();
		search.setSearchFlags(search.getSearchFlags() & ~EnumDSSXMLSearchFlags.DssXmlSearchUsesRecursive );  
		search.setAsync(false );  
		search.types().add(EnumDSSXMLObjectSubTypes.DssXmlSubTypeUserGroup);
		search.setDomain(EnumDSSXMLSearchDomain.DssXmlSearchConfigurationAndAllProjects );
		try {
			search.submit();
			int l = search.getResults().size();
			WebFolder results = search.getResults();
			WebObjectInfo obj;
			String MARC_Base_ObjID = "";
			String ICARD_Base_ObjID = "";
			String Dashboard_Base_ObjID = "";
			for (int x = 0; x < results.size(); x++) {
	             obj = results.get(x);
				if (MARC_Access && BASE_GROUP_MARC.equalsIgnoreCase(obj.getName())) {
					MARC_Base_ObjID = obj.getID();
				}
				if (ICARD_Access && BASE_GROUP_ICARD.equalsIgnoreCase(obj.getName())) {
					ICARD_Base_ObjID = obj.getID();
				}
				if (Dashboard_Access && BASE_GROUP_DASHBOARD.equalsIgnoreCase(obj.getName())) {
					Dashboard_Base_ObjID = obj.getID();
				}
	         } 
	         if(!MARC_Base_ObjID.equalsIgnoreCase("")){
	        	 result.add(SearchGroups(MARC_Base_ObjID,sessioninfo));
	         }
             if(!ICARD_Base_ObjID.equalsIgnoreCase("")){
            	 result.add(SearchGroups(ICARD_Base_ObjID,sessioninfo));
	         }
             if(!Dashboard_Base_ObjID.equalsIgnoreCase("")){
            	 result.add(SearchGroups(Dashboard_Base_ObjID,sessioninfo));
	         }
		} catch (WebObjectsException e) {
			e.printStackTrace();
		}
		
      return result;
	}
    public static WebIServerSession GetAdminSession(MSLogin user){
        
        WebObjectsFactory objectFactory = WebObjectsFactory.getInstance();
		WebIServerSession sessionInfo = objectFactory.getIServerSession();
		sessionInfo.setServerName(user.getServerName());
		sessionInfo.setLogin(user.getUsername());
		sessionInfo.setPassword(user.getPassword());
		sessionInfo.setApplicationType(EnumDSSXMLApplicationType.DssXmlApplicationCustomApp);
    	return sessionInfo;
    }

	public static int ChildrenCount(String GUID,WebIServerSession sessioninfo){
		int userCount =0;
		UserGroupBean parent = (UserGroupBean)BeanFactory.getInstance().newBean("UserGroupBean");
		parent.setSessionInfo(sessioninfo);
		parent.setObjectID(GUID);
		try {
			UserEntitiesBean ueb = parent.getChildren();
			userCount = ueb.size();
			}catch (WebBeanException e) {
				e.printStackTrace();
			}
		return userCount;
	}

	public static List<SecurityGroupBean> SearchGroups(String Base_ObjID, WebIServerSession session) {
		List<SecurityGroupBean> list = new ArrayList<SecurityGroupBean>();
		try {
			UserGroupBean parent = (UserGroupBean) BeanFactory.getInstance().newBean("UserGroupBean");
			parent.setSessionInfo(session);
			parent.setObjectID(Base_ObjID);
			UserEntitiesBean ueblevel1 = parent.getChildren();
			for (int lvl1 = 0; lvl1 < ChildrenCount(Base_ObjID, session); lvl1++) {
	        	
				// Level 1----------------------------
				SecurityGroupBean bean1 = new SecurityGroupBean();
				bean1.setGroupID(ueblevel1.get(lvl1).getObjectID());
				bean1.setGroupName(ueblevel1.get(lvl1).getObjectName());
				bean1.setGroup(ueblevel1.get(lvl1).isGroup());
				list.add(bean1);
				// Level 1----------------------------
				//System.out.println("Level1: " + bean1.getGroupName());

				if (bean1.isGroup()) {
					UserGroupBean parentlvl1 = (UserGroupBean) BeanFactory.getInstance().newBean("UserGroupBean");
					parentlvl1.setSessionInfo(session);
					parentlvl1.setObjectID(bean1.getGroupID());
					UserEntitiesBean ueblevel2 = parentlvl1.getChildren();
		        	   
					for (int lvl2 = 0; lvl2 < ChildrenCount(bean1.getGroupID(), session); lvl2++) {
	        			 if(ueblevel2.get(lvl2).isGroup()){  
		        			// System.out.println("Level2: " +ueblevel2.get(lvl2).getObjectName());
		        			 String Objectlvl2ID = ueblevel2.get(lvl2).getObjectID();
		        			 
		        			 // Level 2 -------------------------------------------
		        			 SecurityGroupBean bean2 = new SecurityGroupBean();
		        			 bean2.setGroupID(ueblevel2.get(lvl2).getObjectID());
		        			 bean2.setGroupName(ueblevel2.get(lvl2).getObjectName());
		        			 bean2.setGroup(ueblevel1.get(lvl2).isGroup());
		        			 bean1.addChild(bean2);
		        			 // Level 2 -------------------------------------------

							if (ueblevel1.get(lvl2).isGroup()) {
								UserGroupBean parentlvl2 = (UserGroupBean) BeanFactory.getInstance().newBean("UserGroupBean");
								parentlvl2.setSessionInfo(session);
								parentlvl2.setObjectID(Objectlvl2ID);
								UserEntitiesBean ueblevel3 = parentlvl2.getChildren();
								for (int lvl3 = 0; lvl3 < ChildrenCount(Objectlvl2ID, session); lvl3++) {
				        		   	 
									// Level 3 -------------------------------------------
									 SecurityGroupBean bean3 = new SecurityGroupBean();
									 bean3.setGroupID(ueblevel3.get(lvl3).getObjectID());
									 bean3.setGroupName(ueblevel3.get(lvl3).getObjectName());
									 bean3.setGroup(ueblevel3.get(lvl3).isGroup());
									 bean2.addChild(bean3);
									// Level 3 -------------------------------------------
				        		     
									if (ueblevel3.get(lvl3).isGroup()) {
										//System.out.println("Level3: "+ ueblevel3.get(lvl3).getObjectName());
										String Objectlvl3ID = ueblevel3.get(lvl3).getObjectID();
										if (ueblevel3.get(lvl3).isGroup()) {
											UserGroupBean parentlvl3 = (UserGroupBean) BeanFactory.getInstance().newBean("UserGroupBean");
											parentlvl3.setSessionInfo(session);
											parentlvl3.setObjectID(Objectlvl3ID);
											UserEntitiesBean ueblevel4 = parentlvl3.getChildren();
											for (int lvl4 = 0; lvl4 < ChildrenCount(Objectlvl3ID, session); lvl4++) {
												// Level 4 -------------------------------------------
												 SecurityGroupBean bean4 = new SecurityGroupBean();
												 bean3.setGroupID(ueblevel4.get(lvl4).getObjectID());
												 bean4.setGroupName(ueblevel4.get(lvl4).getObjectName());
												 bean4.setGroup(ueblevel4.get(lvl4).isGroup());
												 bean3.addChild(bean4);
												// Level 4 -------------------------------------------
												
												if (ueblevel4.get(lvl4).isGroup()) {
													//System.out.println("Level4: " + ueblevel4.get(lvl4).getObjectName());
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		} catch (Exception e) {
			System.out.println("An exception occured" + e);
		}
		return list;
	}
	
	public static void main(String[] args) {
		MSLogin user = new MSLogin();
		user.setServerName("localhost");
		user.setUsername("Administrator");
		user.setPassword("");
		user.setProducts("MARC, ICARD, Dashboard");
    	List<List<SecurityGroupBean>> list = MDServiceHandler.getGroups(user);
    	System.out.println(Utils.toJSON(list));
	}
}